#include "BoidManager.h"

BoidManager *BoidManager::mInstance = 0;

//! returns a list of boids in the vicinity of a sphere.
void BoidManager::getNeighborhoodBoids(BoidBase *boid, float minDistance, float maxDistance, float cosMaxAngle, BoidList &result)
{
	float squaredMinDistance = minDistance * minDistance;
	float squaredMaxDistance = maxDistance * maxDistance;
	const Ogre::Vector3 &boidPos = boid->getPosition();

	result.clear();
	BoidList::iterator iter = mBoidInstanceList.begin();
	while (iter != mBoidInstanceList.end())
	{
		if (boid == *iter)
		{
			iter++;
			continue; // skip own self.
		}

		float squaredDistance = boidPos.squaredDistance((*iter)->getPosition());
		if (squaredDistance < squaredMinDistance)
		{
			result.push_back(*iter);
		}
		else if (squaredDistance < squaredMaxDistance)
		{
			// test angular offset from forward axis
			Ogre::Vector3 unitOffset((*iter)->getPosition() - boidPos);
			unitOffset.normalise();
			float forwardness = boid->getForwardVector().dotProduct(unitOffset);
			if (forwardness > cosMaxAngle)
			{
				result.push_back(*iter);
			}
		}

		iter++;
	}
}

//! triggered per frame to execute boid simulation.
bool BoidManager::frameStarted(const Ogre::FrameEvent& evt)
{
	BoidList::iterator iter = mBoidInstanceList.begin();
	while (iter != mBoidInstanceList.end())
	{
		(*iter)->steerBoid((*iter)->getBehaviorResult());
		iter++;
	}

	return true;
}
